#include "lv_port_indev.h"
#include "lvgl.h"

#include "sdl2_tp.h"

static sdl2_tp tp;
lv_indev_t* indev_touchpad;
lv_indev_t* indev_keypad;
lv_indev_t* indev_encoder;

void lv_port_indev_event_poll(void)
{
	sdl2_tp_event_poll(&tp);
}

bool lv_port_indev_quit(void)
{
	return sdl2_tp_quit_get(&tp);
}

static bool touchpad_is_pressed(void)
{
	return sdl2_tp_is_pressed(&tp);
}

static void touchpad_get_xy(lv_coord_t* x, lv_coord_t* y)
{
	/**
	 * 由于数据类型不一致
	 * lvgl 是 lv_coord_t 类型，对于 RGB565 来说，其实就是 uint16_t
	 * sdl2_tp 是 int 类型
	 * 防止出现连续内存赋值导致数据覆盖的问题，索性用一个临时变量缓存下
	 */
	int tmpx = 0;
	int tmpy = 0;
	sdl2_tp_get_xy(&tp, &tmpx, &tmpy);

	*x = tmpx;
	*y = tmpy;
}

static void touchpad_read(lv_indev_drv_t* indev_drv, lv_indev_data_t* data)
{
	static lv_coord_t last_x = 0;
	static lv_coord_t last_y = 0;

	/*Save the pressed coordinates and the state*/
	if (touchpad_is_pressed()) {
		touchpad_get_xy(&last_x, &last_y);
		data->state = LV_INDEV_STATE_PR;
	} else {
		data->state = LV_INDEV_STATE_REL;
	}

	/*Set the last pressed coordinates*/
	data->point.x = last_x;
	data->point.y = last_y;
}

static uint32_t keypad_get_key(void)
{
	return sdl2_key_get_keycode(&tp);
}

/*Will be called by the library to read the mouse*/
static void keypad_read(lv_indev_drv_t* indev_drv, lv_indev_data_t* data)
{
	static uint32_t last_key = 0;

	/*Get whether the a key is pressed and save the pressed key*/
	uint32_t act_key = keypad_get_key();
	if (act_key != 0) {
		data->state = LV_INDEV_STATE_PR;

		/*Translate the keys to LVGL control characters according to your key definitions*/
		switch (act_key) {
		case 1:
			act_key = LV_KEY_NEXT;
			break;
		case 2:
			act_key = LV_KEY_PREV;
			break;
		case 3:
			act_key = LV_KEY_LEFT;
			break;
		case 4:
			act_key = LV_KEY_RIGHT;
			break;
		case 5:
			act_key = LV_KEY_ENTER;
			break;
		}

		last_key = act_key;
	} else {
		data->state = LV_INDEV_STATE_REL;
	}

	data->key = last_key;
}

static void encoder_read(lv_indev_drv_t* indev_drv, lv_indev_data_t* data)
{
	data->enc_diff = -sdl2_wheel_get_offset(&tp);
	data->state = sdl2_wheel_get_pressed(&tp);
}

void lv_port_indev_init(void)
{
	static lv_indev_drv_t touchpad_drv;
	static lv_indev_drv_t keypad_drv;
	static lv_indev_drv_t encoder_drv;

	sdl2_tp_init(&tp);

	lv_indev_drv_init(&touchpad_drv);
	touchpad_drv.type = LV_INDEV_TYPE_POINTER;
	touchpad_drv.read_cb = touchpad_read;
	indev_touchpad = lv_indev_drv_register(&touchpad_drv);

	lv_indev_drv_init(&keypad_drv);
	keypad_drv.type = LV_INDEV_TYPE_KEYPAD;
	keypad_drv.read_cb = keypad_read;
	indev_keypad = lv_indev_drv_register(&keypad_drv);

	lv_indev_drv_init(&encoder_drv);
	encoder_drv.type = LV_INDEV_TYPE_ENCODER;
	encoder_drv.read_cb = encoder_read;
	indev_encoder = lv_indev_drv_register(&encoder_drv);

	lv_group_t* group = lv_group_get_default();
	if (!group) {
		group = lv_group_create();
		lv_group_set_default(group);
	}

	lv_indev_set_group(indev_touchpad, group);
	lv_indev_set_group(indev_keypad, group);
	lv_indev_set_group(indev_encoder, group);
}
